package com.example.springstudy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springstudy.dao.dto.OrderDTO;
import com.example.springstudy.dao.res.OrderRes;
import com.example.springstudy.dao.res.WeChatPayRes;
import com.example.springstudy.entity.Order;
import com.example.springstudy.entity.Sku;
import com.example.springstudy.mapper.OrderMapper;
import com.example.springstudy.service.OrderService;
import com.example.springstudy.service.SkuService;
import com.example.springstudy.service.pay.WeChatPaymentService;
import com.example.springstudy.utils.DateUtils;
import com.example.springstudy.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    SkuService skuService;

    @Transactional
    @Override
    public Order createOrder(OrderDTO orderDTO) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper
                .ge(Order::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN))
                .le(Order::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MAX))
                .orderByDesc(Order::getId).last("limit 1");
        List<Order> last = this.list(wrapper);
        Order order = new Order(orderDTO);
        if(!last.isEmpty()){
            order.setOrderNo(generateOrderNumber(last.get(0).getOrderNo()));
        } else {
            order.setOrderNo(generateOrderNumber("00000"));
        }
        order.setTimeStart(DateUtils.defaultDate()); //默认当前下单时间，有预下单活动则为固定时间
        order.setTimeExpire(DateUtils.expireDate(15*60)); //15分钟过期
        order.setStatus(1); //待支付
        order.setCreateBy(SecurityUtils.getUserId());
        order.setCreateTime(DateUtils.defaultDate());
        if(this.save(order)){
            orderMapper.insertOrderSkuList(order.getId(), orderDTO.getSkuList());
            List<Sku> skus = orderDTO.getSkuList().stream().map(i->{
                Sku sku = new Sku();
                sku.setId(i.getSkuId());
                sku.setStock(i.getSkuCount());
                sku.setName(i.getSkuName());
                return sku;
            }).toList();
            skuService.updateSkuStocks(skus, -1);
        }
        return order;
    }

    @Override
    public OrderRes queryOrder(int orderId) {
        return orderMapper.queryOrder(orderId);
    }

    @Override
    public List<OrderRes> queryOrderListByPage(int shopId, int employeeId, int page, int size) {
        return orderMapper.queryOrderListByPage(shopId, employeeId, page, size);
    }

    @Override
    public boolean updateOrder(OrderDTO order) {
        return this.updateById(new Order(order));
    }

    @Transactional
    @Override
    public boolean orderPay(String code, String orderNo, String amount) throws IllegalAccessException {
        Order order = this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, orderNo));
        long now = DateUtils.defaultDate().getTime();
        long start = order.getTimeStart().getTime();
        long expire = order.getTimeExpire().getTime();
        Assert.isTrue(now>start, "预售订单还未到支付时间，不能支付！");
        Assert.isTrue(now<expire, "订单已过期，不能支付");
        Assert.isTrue(order.getAmount() == Integer.parseInt(amount), "支付金额与订单金额不匹配");
        WeChatPayRes res = WeChatPaymentService.scanPay(code, orderNo, amount);
        boolean success = Objects.equals(res.getReturnCode(), "SUCCESS") && Objects.equals(res.getResultCode(), "SUCCESS") && Objects.equals(res.getTradeType(), "MICROPAY");
        if(success){
            order.setStatus(2); //支付成功
        } else {
            order.setStatus(3); //支付失败
        }
        this.updateById(order);
        return success;
    }

    boolean closeOrder(Order order) throws Exception {
        OrderRes res = this.queryOrder(order.getId());
        List<Sku> skus = res.getSkuList().stream().map(i->{
            Sku sku = new Sku();
            sku.setId(i.getSkuId());
            sku.setStock(i.getSkuCount());
            sku.setName(i.getSkuName());
            return sku;
        }).toList();
        int successCount = skuService.updateSkuStocks(skus, 1);
        return successCount==skus.size();
    }

    String generateOrderNumber(String lastOrderNo) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String datePart = dateFormat.format(new Date());
        // 订单号生成逻辑 当日时间加4位序列号 + 8位随机数
        int sequenceNumber = Integer.parseInt(lastOrderNo.substring(lastOrderNo.length()-4));
        Random random = new Random();
        String characters = "0123456789";
        StringBuilder randomStr = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            int index = random.nextInt(characters.length());
            randomStr.append(characters.charAt(index));
        }
        return "ORD" + datePart + String.format("%04d", sequenceNumber+1) + randomStr;
    }
}
